﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Net.Http.Headers;
using System.Diagnostics;
using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json;
using System.Xml.Linq;
using WcMatch.Attributes;
using WcMatch.Consts;
using WcMatch.Models;
using WcMatch.Utility;

namespace WcMatch.Controllers
{
    [Route("[controller]/[action]")]
    [ApiController]
    public class StudentController : ControllerBase
    {   
        StudentContext _studentContext;
        IWebHostEnvironment _webHostEnvironment;
        JobContext _jobContext;
        CompanyContext _cCxt;

        JsonSerializerOptions serializeOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            Converters = { new DateTimeJsonConverter() }
        };

        private readonly ILogger<StudentController> _logger;

        public StudentController(StudentContext studentContext,
                                 IWebHostEnvironment webHostEnvironment,
                                 JobContext jobContext,
                                 CompanyContext cCxt,
                                 ILogger<StudentController> logger)
        {
            _webHostEnvironment = webHostEnvironment;
            _studentContext = studentContext;
            _jobContext = jobContext;
            _logger = logger;
            _cCxt = cCxt;
        }


        [HttpPost]
        public async Task<IActionResult> Register(string uname, string pwd)
        {
            if(string.IsNullOrEmpty(uname) || string.IsNullOrEmpty(pwd))
                return BadRequest(new ActionStatus(-1, "用户名或密码不可为空")); 
            Student stu = _studentContext.Students.Where(s => s.UName == uname).FirstOrDefault();
            if (stu != null)
                return BadRequest(new ActionStatus(-1, "用户名已经存在"));
            stu = new Student(uname, pwd);
            _studentContext.Students.Add(stu);  
            await _studentContext.SaveChangesAsync();
            return Ok(new ActionStatus(200, "注册成功", stu.Uid));
            
        }

        [HttpPost]
        public IActionResult Login(string uname, string pwd)
        {
            Student student = _studentContext.Students.FirstOrDefault(s => s.UName == uname && s.HashedPwd == pwd);
            if (student == null)
                return NotFound(new ActionStatus(-1, "用户不存在", string.Empty));
            return Ok(new ActionStatus(200, "登录成功", student.Uid));
        }

        [HttpGet] 
        public IActionResult GetBasicInfo(string uid)
        {
            if (string.IsNullOrEmpty(uid))
                return BadRequest(new ActionStatus(-1, "参数错误", string.Empty));
            Student stu = _studentContext.Students.Where(s => s.Uid == uid).FirstOrDefault();
            if (stu == null)
                return BadRequest(new ActionStatus(-1, "用户不存在", string.Empty));
            else
                return Ok(new ActionStatus(200, "获取成功", stu));
            //return Ok(new ActionStatus(200, "获取成功", new JsonResult(stu, serializeOptions)));
        }

        [HttpPost]
        public async Task< IActionResult> UpdateInfo(string uid, [FromForm]IFormCollection dict)
        {
            if (string.IsNullOrEmpty(uid))
                return BadRequest(new ActionStatus(-1, "参数错误", string.Empty));
            Student? stu = _studentContext.Students.Where(s => s.Uid == uid).FirstOrDefault();
            if (stu == null)
                return NotFound(new ActionStatus(-1, "用户不存在", string.Empty));
            if (ParseUpdateInfoForm(dict, ref stu))
            {
                await _studentContext.SaveChangesAsync();
                return Ok(new ActionStatus(200, "用户信息更新成功", stu));
            }
            else
                return BadRequest(new ActionStatus(-1, "更新失败", stu.Uid));
        }

        private bool ParseUpdateInfoForm(IFormCollection dict, ref Student stu)
        {
            PropertyInfo[] pis = stu.GetType().GetProperties();
            foreach (PropertyInfo prop in pis)
            {
                if (dict.ContainsKey(prop.Name) && dict[prop.Name].Count() != 0)
                {
                    var value = dict[prop.Name][0];
                    Console.WriteLine(prop.Name);
                    if (prop.PropertyType.FullName.Contains("DateTime"))
                        prop.SetValue(stu, DateTime.Parse(value));
                    else
                        prop.SetValue(stu, value);
                }
            }
            return true;
        }


        [HttpGet]
        public IActionResult LoadingPhoto(string uid)
        {
            if (string.IsNullOrEmpty(uid))
                return BadRequest(new ActionStatus(-1, "参数异常", string.Empty));
            Student? stu = _studentContext.Students.Where(s => s.Uid == uid).FirstOrDefault();
            if(stu == null)
                return NotFound(new ActionStatus(-1, "用户不存在", string.Empty));
            else if(string.IsNullOrEmpty(stu.Photo))
                return NotFound(new ActionStatus(-1, "用户照片不存在", string.Empty));

            var dirPath = Path.Combine(_webHostEnvironment.ContentRootPath + GlobalDefines.StuPhotoDir);
            if (!Directory.Exists(dirPath))
                return NotFound(new  ActionStatus (-1, "内部异常", string.Empty));

            string ext = Path.GetExtension(stu.Photo).ToLower();
            var contentTypeStr = GlobalDefines.ImgTypeDict[ext];
            using (var fs = new FileStream(stu.Photo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var bytes = new byte[fs.Length];
                fs.Read(bytes, 0, bytes.Length);
                fs.Close();
                return Ok(new ActionStatus(200, "获取成功", new FileContentResult(bytes, contentTypeStr)));
            }
        }

        //https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/mvc/models/file-uploads/samples/5.x/LargeFilesSample/Controllers/FileUploadController.cs
        //https://learn.microsoft.com/zh-cn/aspnet/core/mvc/models/file-uploads?view=aspnetcore-6.0 


        [HttpPost]
        public async Task<IActionResult> UploadPhoto(string uid,[FromForm]IFormCollection dict)
        {
            if(string.IsNullOrEmpty(uid))
                return BadRequest(new ActionStatus(-1, "参数异常", string.Empty));
            var stu = _studentContext.Students.Where(s => s.Uid == uid).FirstOrDefault();
            if (stu == null)
                return BadRequest(new ActionStatus(-1, "用户不存在", string.Empty));

            IFormFile photo = dict.Files["photo"];
            if(photo == null)
                return BadRequest(new ActionStatus(-1, "参数异常", string.Empty));



            string fileExten = Path.GetExtension(photo.FileName).ToLower();
            if (!GlobalDefines.ImgTypeDict.Keys.Contains(fileExten))
                return BadRequest(new ActionStatus(-1, "上传图片格式错误", string.Empty));
            var dirPath = Path.Combine(_webHostEnvironment.ContentRootPath + GlobalDefines.StuPhotoDir);
            if (!Directory.Exists(dirPath))
                Directory.CreateDirectory(dirPath);
            string filePath = Path.Combine(dirPath, stu.Uid + Path.GetExtension(photo.FileName));

            using (var fs = System.IO.File.Create(filePath))
            {
                await photo.CopyToAsync(fs);
            }
            stu.Photo = filePath;            
            await _studentContext.SaveChangesAsync();
            return Ok(new ActionStatus(200, "上传成功", stu.Uid));
        }

        [HttpGet]
        public async Task<IActionResult> GetJobs(string uid)
        {
            if (string.IsNullOrEmpty(uid))
                return BadRequest(new ActionStatus(-1, "参数异常"));
            Student stu = _studentContext.Students.Where(s => s.Uid == uid).FirstOrDefault();
            if (stu == null) return BadRequest(new ActionStatus(-1, "参数异常"));

            var js = _jobContext.Jobs.Where(s => s.CollegeRequirement == stu.College && s.MajorRequirement == stu.Major);
            return Ok(new ActionStatus(200, "获取成功",js  ));
        }

        [HttpGet]
        public IActionResult GetCuidByCid(string cid)
        {
            //根据企业id获取企业uid
            if (string.IsNullOrEmpty(cid)) return BadRequest(new ActionStatus(-1, "参数异常"));
            var c = _cCxt.Companies.Where(s=>s.CompanyId == cid).FirstOrDefault();
            if (c != null) return Ok(new ActionStatus(200, "查找成功", c.Uid));
            else return NotFound(new ActionStatus(-1, "未查询到"));
        }

        [HttpGet]
        public IActionResult GotoCompany(string uid) {
            //根据企业uid跳转到企业主页
            if (string.IsNullOrEmpty(uid)) return BadRequest(new ActionStatus(-1, "参数异常"));
            var c = _cCxt.Companies.Where(s => s.Uid == uid).FirstOrDefault();
            if (c != null) return Ok(new ActionStatus(200, "查找成功", c));
            else return NotFound(new ActionStatus(-1, "未查询到"));
        }
    }
}
